package com.atguigu.zy.interview.juc.thread;


import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;

/**
 * 3、实现 Callable
 * 会抛异常
 */
class MyThread implements Callable<Integer> {

    @Override
    public Integer call() throws Exception {
        System.out.println(Thread.currentThread().getName()+"\t come in callable");

        //@formatter:off  线程暂停 2 秒
        try { TimeUnit.SECONDS.sleep( 2 ); } catch (InterruptedException e) { e.printStackTrace();}
        //@formatter:on
        return 1024;
    }
}


/**
 * @author Jungle
 * @create 2022-09-03 12:57
 * @formatter:off
 * 创建线程的3中方法
 *    1、继承Thread
 *    2、实现Runnable
 *    3、实现 Callable  唯一可以抛异常(业务需要)  ,有返回值，抛异常
 *      适配器模式
 *      ==>FutureTask--》RunnableFuture-->Runnable       ==>类    --> 接口
 * @formatter:on
 *
 */
public class CallableDemo {
    public static void main(String[] args) throws ExecutionException, InterruptedException {

        //两个线程，一个main线程，一个AA futureTask线程
        //FutureTask(Callable<V> callable)
        FutureTask<Integer> futureTask = new FutureTask<Integer>(new MyThread());
        //FutureTask<Integer> futureTask1 = new FutureTask<Integer>(new MyThread());
        //多个线程执行同一个futureTask，只会执行一次 call（）,多个futureTask对象才会执行多次
        new Thread(futureTask,"AA").start();
        //new Thread(futureTask1,"BB").start();
        //int result02 = futureTask.get();

        System.out.println(Thread.currentThread().getName()+"\t ****************");
        int result01 = 100;

        /**
         * 1、使用自旋锁，，get方法不用阻塞
         */
        //while (!futureTask.isDone()) {
        //
        //}
        //要求Callable线程的计算结果，如果没有计算完成就去强求，就会导致阻塞，直到计算结果完成
        int result02 = futureTask.get();
        System.out.println(Thread.currentThread().getName()+"\t 返回结果\t"+(result01+result02));

    }
}
